package client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

/**
 * Auction-Client, used to connect to an Auction-Server.
 * Users can create Auctions, list Auctions and bid on Auctions.
 * The Client sends Messages via TCP and receives Answers.
 * The Client is also listening for UDP-Messages from the server.
 * @author Andreas Mair
 */
public class Client 
implements Stoppable
{
	private String serverHost;
	private int tcpPort;
	private int udpPort;
	
	private Socket tcpSocket;
	private BufferedReader brStdIn;
	private InputStreamReader inputStream;
	private boolean bStop=false;
	
	/**
	 * Client Constructor
	 * @param serverHost Host name or IP of the auction server
	 * @param tcpPort TCP connection port on which the auction server is listening for connections
	 * @param udpPort will be used for UDP-Notifications from the auction server
	 * @throws NumberFormatException if tcpPort or udpPort aren't numeric
	 */
	public Client(String serverHost,String tcpPort,String udpPort) throws NumberFormatException
	{
		this.serverHost=serverHost;
		this.tcpPort=Integer.parseInt(tcpPort);
		this.udpPort=Integer.parseInt(udpPort);
	}
	
	/**
	 * Starts the client, creates a Thread for incoming TCP-Messages and listens
	 * for commands on the command line.
	 * Therefore Sockets are created, ....
	 */
	public void start()
	{
		try
		{
			tcpSocket=new Socket(serverHost,tcpPort);
			Thread tcpInputThread=new Thread(new TCPListenerThread(tcpSocket.getInputStream(),this,udpPort));
			tcpInputThread.start();
			
			inputStream=new InputStreamReader(System.in);
			brStdIn=new BufferedReader(inputStream);
			String strLine;
			PrintWriter out=new PrintWriter(tcpSocket.getOutputStream(),true);
			while(!bStop)
			{
				if(brStdIn.ready())
				{
					strLine=brStdIn.readLine();
					if(strLine.startsWith("!login"))
					{
						strLine=strLine+" "+udpPort;
					}
					out.println(strLine);
					if(strLine=="!end")
					{
						break;
					}
				}
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					//ignore
				}
			}
		}
		catch(UnknownHostException uhe)
		{
			System.out.println("The Server '"+serverHost+"' could not be found!");
		}
		catch(SocketException ex)
		{
			System.out.println("Socketexception occured, is the server running? "+ex.getMessage());
		}
		catch(IOException ioex)
		{
			System.out.println("IOException occured "+ioex.getMessage());
		}
		finally
		{
			System.out.println("Reading from stdin stops...");
			this.stop();
		}
	}
	
	@Override
	public synchronized void stop() 
	{
		if(!bStop)
		{
			bStop=true;
			try 
			{
				if(brStdIn!=null)
				{
					brStdIn.close();
				}
			}
			catch (IOException e) 
			{
				//ignore
			}
			try 
			{
				if(tcpSocket!=null && !tcpSocket.isClosed())
				{
					tcpSocket.close();
				}
			}
			catch (IOException e) 
			{
				//ignore
			}
			System.out.println("Client stopped!");
		}
	}	
}
